#include <SPI.h>
#include <EthernetUdp.h>
#include <EthernetClient.h>
#include <Ethernet.h>
#include <Dhcp.h>
#include <Dns.h>
#include <EthernetServer.h>
#include <util.h>


//======================================
// User Configurations
//======================================
const int BESS_MSG    = 7;
const int BESS_POLL   = 6;
const int BESS_SIGNAL = 5;
const int intPin      = 2;  // the interrupt pin
const int adactive    = 3;  // Analog Pin Signal
//======================================
// User Configurations
//======================================
int user   = 1;    // 1 = Kyrkvardsvagen 32
int implev = 10;   // Threshold for detecting impuls
int loglev = 1;    // Detailed logging on/off  1/0
//======================================
// Global Declarations
//======================================
unsigned long curTime, prevTime, deltaTime;
int x, state = 0, nWatt=0;
float watt0,watt1;
int value_0 = 0, value_1=0,value_2=0,value_3=0;
int nloop = 0, nblink = 0;
int i,nBytes=0;
char c,sconf[800];

const int TRIGLEVEL = 2;       // triglevel on analog signal 1023 = 5.0V
const int UNTRIGLEVEL = 1;

#define KWHC (3600000L)    // pwr at one pulse per ms, i.e. 1000 pulses per kwh.

// Variables will change:
int foo;

struct intdata {
  /* internal data */
  volatile int base;
  volatile int baserem;
  volatile int sig;
  volatile int sigrem;
  volatile int trig;
  volatile long prevtime;
  volatile int pulses;
  /* external data for background prog */
  volatile int ptrig;
  volatile int ppulses;
  volatile long powertime;
  volatile long power; 
  volatile int sigmax;
} id1;

volatile long adint = 0;

void iniid(struct intdata *id)
{
  id->base = 0;
  id->sig  = 0;
  id->trig = 0;
  id->prevtime = 0;
  id->pulses = 0;
}

//======================================

byte mac[]  = { 0x90, 0xA2, 0xDA, 0x00, 0x29, 0x66 };
//byte ip[]   = {192 , 168, 1, 200 };
byte ip[]   = {192 , 168, 1, 66 };
byte server[] = {192, 168, 1, 176 };
//byte server[] = {192, 168, 5, 2 };
//byte server[] = {83, 226, 198, 188 }; // simuino.com

EthernetClient client;
//======================================
void blink(int led,int n, int freq)
//======================================
{
  int i;
  digitalWrite(led,LOW);
  delay(freq);
  for(i=0;i<n;i++)
    {
      digitalWrite(led,HIGH);
      delay(freq);
      digitalWrite(led,LOW);
      delay(freq);
    }
}
//======================================
int getValue(char *s, char q[40])
//======================================
{
  char *p;
  int res = 0;
  if(p=strstr(s,q))
    {
      p=strstr(p,"=");
      p++;
      //Serial.println(p);
      sscanf(p,"%d",&res);
    }
  return(res);
}

//======================================
void adpoll()
//======================================
{ 
  int ad1;
  int tmp, stmp;
  long tmpl;
    
  digitalWrite(BESS_POLL, 1);
  adint++;
    
  ad1 = analogRead(adactive);
    
    
  // filter base, tau = 0.256 seconds.
  tmp = (ad1 - id1.base + id1.baserem) & 0xff;
  id1.base = id1.base + ((ad1 - id1.base + id1.baserem) >> 8);
  id1.baserem = tmp;
    
  // filter sig, tau = 0.004 seconds.
  stmp = ad1 - id1.base;
  tmp = (stmp - id1.sig + id1.sigrem) & 0x03;
  id1.sig = id1.sig + ((stmp - id1.sig + id1.sigrem) >> 2);
  id1.sigrem = tmp;
    
  if (id1.sig > id1.sigmax) id1.sigmax = id1.sig;
    
  if ((id1.trig) && (id1.sig < UNTRIGLEVEL)) 
    {
      id1.trig = 0;
      digitalWrite(BESS_SIGNAL, 0);
    }
    
  if ((id1.trig == 0) && (id1.sig >= TRIGLEVEL)) 
    {
      id1.trig = 1;  // we found a pulse
      digitalWrite(BESS_SIGNAL, 1);  // mirror input to output  
      id1.pulses++;
      if (id1.sig > id1.sigmax) id1.sigmax = id1.sig;
      tmpl = adint - id1.prevtime;
      if (tmpl >= 10000) 
	{       // more than 10 seconds? 
	  id1.power =  id1.pulses * KWHC / tmpl;
	  id1.powertime = tmpl;
	  id1.prevtime = adint;
	  id1.ppulses = id1.pulses;
	  id1.pulses = 0;
	  id1.ptrig = 1;            // calculated a value... need to print...
	}
    }
    
  digitalWrite(BESS_POLL, 0);
}

//======================================
void setup()
//======================================
{
  pinMode(BESS_MSG,OUTPUT);
  pinMode(BESS_SIGNAL,OUTPUT);
  pinMode(BESS_POLL,OUTPUT);  
  pinMode(intPin,OUTPUT);
  
  Serial.begin(9600);
  
  adint = 0;
  iniid(&id1);

  attachInterrupt(0, adpoll, FALLING);

  digitalWrite(BESS_MSG,HIGH);
  delay(3000); 
  digitalWrite(BESS_MSG,LOW);

  Ethernet.begin(mac, ip);
  delay(1000);

  // Get configuration from BESS server
  blink(BESS_MSG,1,200);
  if (client.connect(server, 80)) {
    Serial.println("Xconnected");
    //client.print("GET /bess/data.php?conf=");
    client.print("GET /data.php?conf=");
    client.print(user);
    client.println(" HTTP/1.1");
    client.println("Host: bess.simuino.com");
    //client.println("Host: 127.0.0.1");
    client.println();
  } else {
    Serial.println("Xconnection failed");
    blink(BESS_SIGNAL,5,200);
  }
  
  delay(3000);  // Give time to receive answer from BESS Server
  nBytes = client.available();
  Serial.println(nBytes);
  
  if (nBytes > 0) 
    {
      for(i=0;i<nBytes;i++)
	{
	  c = client.read();
	  sconf[i] = c;
	  Serial.print(c);
	}
    
      //    implev = getValue(sconf,"implev");
      //    Serial.print("implev= ");
      //    Serial.println(implev);
      //    //loglev = getValue(sconf,"loglev");
      //    //Serial.print("loglev= ");
      //    //Serial.println(loglev);
      //    if(implev == 0)
      //    {
      //       blink(BESS_SIGNAL,9,200);
      //       implev = 10;
      //    }
    }
  blink(BESS_MSG,1,200);
  
  tone(intPin, 1000);
}

//======================================
void loop()
//======================================
{

  //Serial.println(id1.sig);
  
  if (id1.ptrig == 1) 
    {
      Serial.print("Time ");
      Serial.print(id1.powertime);
      Serial.print("; Puls ");
      Serial.print(id1.ppulses);
      Serial.print("; Power ");
      Serial.print(id1.power);
      Serial.print("; Base ");
      Serial.print(id1.base);
      Serial.print("; Sigmax ");
      Serial.print(id1.sigmax);
      Serial.println("; ");
      id1.sigmax = 0;
      id1.ptrig = 0;

      client.stop();
      
      if (client.connect(server, 80)) 
	{
	  blink(BESS_MSG,2,200);
	  client.print("GET /data.php?user=1&time=");
	  //client.print("GET /bess/data.php?user=1&time=");
	  client.print(id1.powertime);
              
	  client.print("&puls=");
	  client.print(id1.ppulses);
              
	  client.print("&power=");
	  client.print(id1.power);
              
	  client.print("&base=");
	  client.print(id1.base);
              
	  client.print("&sigmax=");
	  client.print(id1.sigmax);
              
	  client.println(" HTTP/1.1");
	  client.println("Host: bess.simuino.com");
	  //client.println("Host: 127.0.0.1");
	  client.println();
	} 
      else 
	{
	  blink(BESS_SIGNAL,5,200);
	}
    }
  
}
